using System;
using System.Data;
using PCSComUtils.Common;
using PCSComUtils.PCSExc;
using PCSComUtils.Common.DS;
using PCSComUtils.MasterSetup.DS;
using PCSComMaterials.Inventory.DS;
using PCSComUtils.Common.BO;
using PCSComProduct.Items.DS;
using PCSComProduct.Items.BO;
using PCSComProduct.Costing.DS;
using System.Transactions;
using PCSComUtils.DataContext;
using PCSComUtils.DataAccess;
using System.Linq;
using System.Text;
using log4net;

namespace PCSComMaterials.Inventory.BO
{
    public class InventoryUtilsBO
    {
        private ILog _logger = LogManager.GetLogger(typeof(IVInventoryAdjustmentBO));

        private CommonDS dsCommon = new CommonDS();

        #region Reservered Methods
        /// <summary>
        /// Insert a new record into database
        /// </summary>
        //[AutoComplete(true)]
        public void Add(object pObjectDetail)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Delete record by condition
        /// </summary>
        //[AutoComplete(true)]
        public void Delete(object pObjectVO)
        {
            throw new NotImplementedException();
        }


        /// <summary>
        /// Get the object information by ID of VO class
        /// </summary>
        //[AutoComplete(true)]
        public object GetObjectVO(int pintID, string VOclass)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Return the DataSet (list of record) by inputing the FieldList and Condition
        /// </summary>
        //[AutoComplete(true)]
        public void UpdateDataSet(DataSet dstData)
        {

        }
        //[AutoComplete(true)]
        public void ImportData(DataSet dstData)
        {
            IV_BinCacheDS dsBin = new IV_BinCacheDS();
            dsBin.ImportData(dstData);
        }

        /// <summary>
        /// Update into Database
        /// </summary>
        //[AutoComplete(true)]
        public void Update(object pObjectDetail)
        {
            throw new NotImplementedException();
        }


        //[AutoComplete(true)]
        public int GetPurposeCode(int pintPurposeID)
        {
            return dsCommon.GetPurposeCode(pintPurposeID);
        }
        #endregion Reservered

        #region Quantity Related Methods

        //[AutoComplete(true)]
        public void UpdateAllQuantityFromBin()
        {
            IV_LocationCacheDS dsLocCache = new IV_LocationCacheDS();
            dsLocCache.UpdateAllQuantityFromBin();
            IV_MasLocCacheDS dsMasLocCache = new IV_MasLocCacheDS();
            dsMasLocCache.UpdateAllQuantityFromLocation();
        }

        //[AutoComplete(true)]
        public DataTable GetAvailableQtyByPostDate(DateTime pdtmPostDate)
        {
            IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
            return dsBinCache.GetAvailableQtyByPostDate(pdtmPostDate);
        }
        //[AutoComplete(true)]
        public DataTable GetAvailableQty(string strProductIDs)
        {
            IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
            return dsBinCache.GetAvailableQty(strProductIDs);
        }
        /// <summary>
        /// Determine that Product is existed in Bin yet
        /// </summary>
        /// <param name="pintBinID">Bin to check</param>
        /// <param name="pintProductID">Product to check</param>
        /// <returns>true if exist, false if not exist</returns>
        //[AutoComplete(true)]
        public bool IsHasProductInBin(int pintBinID, int pintProductID)
        {
            IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
            return dsBinCache.IsHasProductInBin(pintBinID, pintProductID);
        }
        //[AutoComplete(true)]
        public void CheckQuantity()
        {
        }
        private bool HasProductLoc(int iProductID, int iCCNID, int iMasterLocationID, int iLocationID, string strLot, PCSDataContext db)
        {
            bool ret = false;
            using (var trans = new TransactionScope())
            {
                try
                {
                    if (db == null) db = new PCSDataContext(Utils.Instance.ConnectionString);
                    var iCount = (from obj in db.IV_LocationCaches
                                  where obj.ProductID == iProductID && obj.CCNID == iCCNID && obj.MasterLocationID == iMasterLocationID && obj.LocationID == iLocationID
                                  && ((strLot != string.Empty && obj.Lot == strLot.Replace(",", "''")) || strLot == string.Empty)
                                  select obj.ProductID).Count();
                    if (iCount > 0) ret = true;
                    else ret = false;
                }
                catch
                { }
                finally
                {
                    trans.Complete();
                }
                return ret;
            }
        }
        private bool HasProductMasLoc(int iProductID, int iCCNID, int iMasterLocationID, int iLocationID, string strLot, PCSDataContext db)
        {
            bool ret = false;
            using (var trans = new TransactionScope())
            {
                try
                {
                    if (db == null) db = new PCSDataContext(Utils.Instance.ConnectionString);
                    var iCount = (from obj in db.IV_MasLocCaches
                                  where obj.ProductID == iProductID && obj.CCNID == iCCNID && obj.MasterLocationID == iMasterLocationID
                                  && ((strLot != string.Empty && obj.Lot == strLot.Replace(",", "''")) || strLot == string.Empty)
                                  select obj.ProductID).Count();
                    if (iCount > 0) ret = true;
                    else ret = false;
                }
                catch
                { }
                finally
                {
                    trans.Complete();
                }
                return ret;
            }
        }
        private bool HasProductBin(int iProductID, int iCCNID, int iMasterLocationID, int iLocationID, int iBinID, string strLot, PCSDataContext db)
        {

            bool ret = false;
            using (var trans = new TransactionScope())
            {
                try
                {
                    if (db == null) db = new PCSDataContext(Utils.Instance.ConnectionString);
                    var iCount = (from obj in db.IV_BinCaches
                                  where obj.ProductID == iProductID && obj.CCNID == iCCNID && obj.MasterLocationID == iMasterLocationID && obj.LocationID == iLocationID && obj.BinID == iBinID
                                  && ((strLot != string.Empty && obj.Lot == strLot.Replace(",", "''")) || strLot == string.Empty)
                                  select obj.ProductID).Count();
                    if (iCount > 0) ret = true;
                    else ret = false;
                }
                catch
                { }
                finally
                {
                    trans.Complete();
                }
                return ret;
            }
        }
        private bool HasSerial(int iProductID, string strSerial)
        {
            using (var trans = new TransactionScope())
            {
                using (var db = new PCSDataContext(Utils.Instance.ConnectionString))
                {
                    //var iCount = (from obj in db.IV_ItemSerial
                    //              where obj.ProductID == iProductID && obj.CCNID == iCCNID && obj.MasterLocationID == iMasterLocationID && obj.LocationID == iLocationID
                    //              && ((strLot != string.Empty && obj.Lot == strSerial.Replace(",", "''")) || true)
                    //              select obj.ProductID).Count();
                    //strSql = "SELECT COUNT(*) "
                    //+ " FROM " + IV_ItemSerialTable.TABLE_NAME
                    //+ " WHERE " + IV_ItemSerialTable.SERIAL_FLD + "= ?"
                    //+ " AND " + IV_ItemSerialTable.CCNID_FLD + "= ?";
                    //if (iCount > 0) return true;
                    //else return false;
                    return true;
                }
            }
        }
        /// <summary>
        /// Update OHQty All
        /// </summary>
        /// <param name="iCNNID"></param>
        /// <param name="iMasterLocationID"></param>
        /// <param name="iLocationID"></param>
        /// <param name="iProductID"></param>
        /// <param name="iBinID"></param>
        /// <param name="dectQty"></param>
        /// <param name="decCommitQty"></param>
        /// <param name="strLot"></param>
        /// <param name="strSerial"></param>
        /// <param name="isSubstractBin"></param>
        /// <param name="isSubstractLocation"></param>
        /// <param name="isSubstractMas"></param>
        /// <param name="isCommitBin"></param>
        /// <param name="isCommitLocation"></param>

        public void UpdateAddOHQtyAll(int iCNNID, int iMasterLocationID, int iLocationID, int iProductID, int? iBinID, decimal dectQty, decimal decCommitQty, string strLot, string strSerial, bool isSubstractBin, bool isSubstractLocation, bool isSubstractMas, bool isCommitBin, bool isCommitLocation, PCSDataContext db)
        {
            using (var trans = new TransactionScope())
            {
                string strQty = dectQty.ToString().Replace(",", ".");
                string strCommitQty = decCommitQty.ToString().Replace(",", ".");
                //using (var db = new PCSDataContext(Utils.Instance.ConnectionString))
                if (db == null) db = new PCSDataContext(Utils.Instance.ConnectionString);
                try
                {
                    if (!HasProductLoc(iProductID, iCNNID, iMasterLocationID, iLocationID, strLot, db))
                    {
                        //Create new LocationCache object 
                        IV_LocationCache voLocationCache = new IV_LocationCache();

                        //Set transfer values to object
                        voLocationCache.CCNID = iCNNID;
                        voLocationCache.Lot = strLot;
                        voLocationCache.MasterLocationID = iMasterLocationID;
                        voLocationCache.ProductID = iProductID;
                        voLocationCache.OHQuantity = 0;
                        voLocationCache.LocationID = iLocationID;

                        //Set default values to object
                        voLocationCache.CommitQuantity = 0;
                        voLocationCache.DemanQuantity = 0;
                        voLocationCache.SupplyQuantity = 0;
                        db.IV_LocationCaches.InsertOnSubmit(voLocationCache);
                    }
                    # region Update OHQtyLoc
                    if (isSubstractLocation)
                    {
                        var objLocation = db.IV_LocationCaches.SingleOrDefault(e => e.LocationID == iLocationID && e.ProductID == iProductID && e.CCNID == iCNNID && e.MasterLocationID == iMasterLocationID );
                        if (objLocation != null)
                        {
                            if (objLocation.OHQuantity != null)
                            {
                                objLocation.OHQuantity = objLocation.OHQuantity - Convert.ToDecimal(strQty);
                            }
                            if (isCommitLocation)
                            {
                                if (objLocation.CommitQuantity != null)
                                {
                                    objLocation.CommitQuantity = objLocation.CommitQuantity - Convert.ToDecimal(strCommitQty);
                                }
                            }
                        }
                    }
                   
                    # endregion
                    //Update OHQtyMasLoc
                    if (!HasProductMasLoc(iProductID, iCNNID, iMasterLocationID, iLocationID, strLot, db))
                    {
                        //Create new MasLocCache object 
                        IV_MasLocCache voMasLocCache = new IV_MasLocCache();

                        //Set transfer values to object
                        voMasLocCache.CCNID = iCNNID;
                        voMasLocCache.Lot = strLot;
                        voMasLocCache.MasterLocationID = iMasterLocationID;
                        voMasLocCache.ProductID = iProductID;
                        voMasLocCache.OHQuantity = 0;

                        //Set default values to object
                        voMasLocCache.CommitQuantity = 0;
                        voMasLocCache.DemanQuantity = 0;
                        voMasLocCache.SummItemCost21 = 0;
                        voMasLocCache.SupplyQuantity = 0;
                        //call add method to add new
                        db.IV_MasLocCaches.InsertOnSubmit(voMasLocCache);
                    }
                    if (isSubstractMas)
                    {
                        var objMasLocation = db.IV_MasLocCaches.SingleOrDefault(e => e.MasterLocationID == iMasterLocationID && e.ProductID == iProductID  && e.CCNID==iCNNID);
                        if (objMasLocation != null)
                        {
                            if (objMasLocation.OHQuantity != null)
                            {
                                objMasLocation.OHQuantity = objMasLocation.OHQuantity - Convert.ToDecimal(strQty);
                            }
                        }
                       
                    }
                    //Update OHQtyBin
                    if (iBinID != null && iBinID > 0)
                    {
                        if (!HasProductLoc(iProductID, iCNNID, iMasterLocationID, iLocationID, strLot, db))
                        {
                            //Create new BinCache object 
                            IV_BinCache voBinCache = new IV_BinCache();

                            //Set transfer values to object
                            voBinCache.CCNID = iCNNID;
                            voBinCache.Lot = strLot;
                            voBinCache.MasterLocationID = iMasterLocationID;
                            voBinCache.ProductID = iProductID;
                            voBinCache.OHQuantity = 0;
                            voBinCache.LocationID = iLocationID;
                            voBinCache.BinID = iBinID ?? 0;

                            //Set default values to object
                            voBinCache.CommitQuantity = 0;
                            voBinCache.DemanQuantity = 0;
                            voBinCache.SupplyQuantity = 0;

                            //call add method to add new
                            db.IV_BinCaches.InsertOnSubmit(voBinCache);
                        }
                        
                        if (isSubstractBin)
                        {
                            var objBin = db.IV_BinCaches.SingleOrDefault(e => e.BinID == iBinID && e.CCNID == iCNNID && e.MasterLocationID == iMasterLocationID && e.LocationID == iLocationID && e.ProductID == iProductID);
                            if (objBin != null)
                            {
                                if (objBin.OHQuantity != null)
                                {
                                    objBin.OHQuantity = objBin.OHQuantity - Convert.ToDecimal(strQty);
                                }
                                if (isCommitBin && isCommitLocation)
                                {
                                    if (objBin.CommitQuantity != null)
                                    {
                                        objBin.CommitQuantity = objBin.CommitQuantity - Convert.ToDecimal(strCommitQty);
                                    }
                                }
                            }
                           
                        }
                    }
                    db.SubmitChanges();
                    trans.Complete();
                    
                }
                catch (Exception ex)
                {
                    throw ex;
                    Transaction.Current.Rollback();
                }
               
            }
        }
        /// <summary>
        /// Update substract All
        /// </summary>
        /// <param name="iCNNID">int</param>
        /// <param name="iMasterLocationID">int</param>
        /// <param name="iLocationID">int</param>
        /// <param name="iProductID">int</param>
        /// <param name="iBinID"></param>
        /// <param name="dectQty"></param>
        /// <param name="decCommitQty"></param>
        /// <param name="strLot"></param>
        /// <param name="strSerial"></param>
        /// <param name="isCommitBin"></param>
        /// <param name="isCommitLocation"></param>
        public void UpdatedSubstractOHQtyAll(int iCNNID, int iMasterLocationID, int iLocationID, int iProductID, int? iBinID, decimal decQty, decimal decCommitQty, string strLot, string strSerial, bool isCommitBin, bool isCommitLocation, bool bContinute, PCSDataContext db)
        {
            using (var trans = new TransactionScope())
            {
                if (db == null)
                {
                    db = new PCSDataContext(Utils.Instance.ConnectionString);
                }
                try
                {
                    bool blContinue = true;
                    if (iBinID > 0 && bContinute)
                    {
                        var OnHandOHQty = (from obj in db.IV_BinCaches
                                           where obj.BinID == iBinID && obj.CCNID == iCNNID &&
                                               obj.LocationID == iLocationID && obj.MasterLocationID == iMasterLocationID
                                               && obj.ProductID == iProductID && (strLot == string.Empty || (strLot != string.Empty && obj.Lot == strLot))
                                           select obj.OHQuantity).Sum();
                        blContinue = (OnHandOHQty <= decQty);
                    }
                    if (blContinue)
                    {
                        //Update OHQtyLoc
                        StringBuilder strSql = new StringBuilder();

                        strSql.Append("UPDATE " + IV_LocationCacheTable.TABLE_NAME + " SET ");
                        strSql.Append(IV_LocationCacheTable.OHQUANTITY_FLD + " = ISNULL(" + IV_LocationCacheTable.OHQUANTITY_FLD + ", 0)+  " + decQty.ToString());
                        if (isCommitLocation)
                        { strSql.Append("," + IV_LocationCacheTable.COMMITQUANTITY_FLD + "=" + decCommitQty.ToString()); }
                        strSql.Append(" WHERE " + IV_LocationCacheTable.LOCATIONID_FLD + "= " + iLocationID.ToString());
                        strSql.Append(" AND " + IV_LocationCacheTable.PRODUCTID_FLD + "= " + iProductID.ToString());
                        strSql.Append(" AND " + IV_LocationCacheTable.CCNID_FLD + "= " + iCNNID.ToString());
                        if (strLot.Length > 0)
                            strSql.Append(" AND " + IV_LocationCacheTable.LOT_FLD + "= " + strLot);
                        strSql.Append(" AND " + IV_LocationCacheTable.MASTERLOCATIONID_FLD + "= " + iMasterLocationID.ToString());

                        strSql.Append(" UPDATE " + IV_MasLocCacheTable.TABLE_NAME + " SET ");
                        strSql.Append(IV_MasLocCacheTable.OHQUANTITY_FLD + "= ISNULL(" + IV_MasLocCacheTable.OHQUANTITY_FLD + ", 0) + " + decQty.ToString());
                        strSql.Append(" WHERE " + IV_MasLocCacheTable.MASTERLOCATIONID_FLD + "= " + iMasterLocationID.ToString());
                        strSql.Append(" AND " + IV_MasLocCacheTable.CCNID_FLD + "= " + iCNNID.ToString());
                        if (strLot.Length > 0)
                            strSql.Append(" AND " + IV_MasLocCacheTable.LOT_FLD + "= " + strLot);
                        strSql.Append(" AND " + IV_MasLocCacheTable.PRODUCTID_FLD + "= " + iProductID.ToString());
                        //Update OHQtyBin                        
                        if (iBinID != null && iBinID > 0)
                        {
                            strSql.Append(" UPDATE " + IV_BinCacheTable.TABLE_NAME + " SET ");
                            strSql.Append(IV_BinCacheTable.OHQUANTITY_FLD + "= ISNULL(" + IV_BinCacheTable.OHQUANTITY_FLD + ", 0) + " + decQty.ToString());
                            if (isCommitBin && isCommitLocation)
                            { strSql.Append(" ," + IV_BinCacheTable.COMMITQUANTITY_FLD + "=" + decCommitQty.ToString()); }
                            strSql.Append(" WHERE " + IV_BinCacheTable.BINID_FLD + "= " + iBinID.ToString());
                            strSql.Append(" AND " + IV_BinCacheTable.CCNID_FLD + "= " + iCNNID.ToString());
                            strSql.Append(" AND " + IV_BinCacheTable.MASTERLOCATIONID_FLD + "= " + iMasterLocationID.ToString());
                            strSql.Append(" AND " + IV_BinCacheTable.LOCATIONID_FLD + "= " + iLocationID.ToString());
                            strSql.Append(" AND " + IV_BinCacheTable.PRODUCTID_FLD + "= " + iProductID.ToString());
                            if (!string.IsNullOrEmpty(strLot.Trim()))
                                strSql.Append(" AND " + IV_BinCacheTable.LOT_FLD + "= " + strLot);
                        }
                        if (strSql.Length > 0)
                            db.ExecuteCommand(strSql.ToString());
                    }
                }
                catch (Exception ex)
                {
                    Transaction.Current.Rollback();
                    throw ex;
                }
                finally
                {
                    trans.Complete();
                }
            }
        }
        /// <param name="pdecQuantity">Quantity to add</param>
        //[AutoComplete(true)]

        private void UpdateAddOHQuantityLoc(int pintCCNID, int pintMasterLocationID, int pintLocationID, int pintProductID, decimal pdecQuantity, string pstrLot)
        {

            //validate data
            if (pstrLot == null) pstrLot = string.Empty;

            IV_LocationCacheDS dsLocationCache = new IV_LocationCacheDS();

            //Check if this product does not exist in LocationCache
            if (!dsLocationCache.HasProductID(pintProductID, pintCCNID, pintMasterLocationID, pintLocationID, pstrLot))
            {
                //Create new LocationCache object 
                IV_LocationCacheVO voLocationCache = new IV_LocationCacheVO();

                //Set transfer values to object
                voLocationCache.CCNID = pintCCNID;
                voLocationCache.Lot = pstrLot;
                voLocationCache.MasterLocationID = pintMasterLocationID;
                voLocationCache.ProductID = pintProductID;
                voLocationCache.OHQuantity = 0;
                voLocationCache.LocationID = pintLocationID;

                //Set default values to object
                voLocationCache.CommitQuantity = 0;
                voLocationCache.DemanQuantity = 0;
                voLocationCache.SupplyQuantity = 0;

                //call add method to add new
                dsLocationCache.Add(voLocationCache);
            }

            if (pstrLot.Length != 0)
            {
                dsLocationCache.UpdateAddOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pstrLot, pdecQuantity);
            }
            else
            {
                dsLocationCache.UpdateAddOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity);
            }

        }

        /// <param name="pdecQuantity">Quantity to add</param>
        //[AutoComplete(true)]
        private void UpdateAddOHQuantityMasLoc(int pintCCNID, int pintMasterLocationID, int pintProductID, decimal pdecQuantity, string pstrLot)
        {

            //validate data
            if (pstrLot == null) pstrLot = string.Empty;

            IV_MasLocCacheDS dsMasLocCache = new IV_MasLocCacheDS();

            //Check if this product does not exist in MasLocCache
            if (!dsMasLocCache.HasProductID(pintProductID, pintCCNID, pintMasterLocationID, pstrLot))
            {
                //Create new MasLocCache object 
                IV_MasLocCacheVO voMasLocCache = new IV_MasLocCacheVO();

                //Set transfer values to object
                voMasLocCache.CCNID = pintCCNID;
                voMasLocCache.Lot = pstrLot;
                voMasLocCache.MasterLocationID = pintMasterLocationID;
                voMasLocCache.ProductID = pintProductID;
                voMasLocCache.OHQuantity = 0;

                //Set default values to object
                voMasLocCache.CommitQuantity = 0;
                voMasLocCache.DemanQuantity = 0;
                voMasLocCache.SummItemCost21 = 0;
                voMasLocCache.SupplyQuantity = 0;

                //call add method to add new
                dsMasLocCache.Add(voMasLocCache);
            }

            if (pstrLot.Length != 0)
            {
                dsMasLocCache.UpdateAddOHQuantity(pintCCNID, pintMasterLocationID, pintProductID, pstrLot, pdecQuantity);
            }
            else
            {
                dsMasLocCache.UpdateAddOHQuantity(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity);
            }

        }

        /// <param name="pdecQuantity">Quantity to add</param>
        //[AutoComplete(true)]
        private void UpdateAddOHQuantityBin(int pintCCNID, int pintMasterLocationID, int pintLocationID, int pintBinID, int pintProductID, decimal pdecQuantity, string pstrLot)
        {
            //validate data
            if (pstrLot == null) pstrLot = string.Empty;

            IV_BinCacheDS dsBinCache = new IV_BinCacheDS();

            //Check if this product does not exist in BinCache
            if (!dsBinCache.HasProductID(pintProductID, pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pstrLot))
            {
                //Create new BinCache object 
                IV_BinCacheVO voBinCache = new IV_BinCacheVO();

                //Set transfer values to object
                voBinCache.CCNID = pintCCNID;
                voBinCache.Lot = pstrLot;
                voBinCache.MasterLocationID = pintMasterLocationID;
                voBinCache.ProductID = pintProductID;
                voBinCache.OHQuantity = 0;
                voBinCache.LocationID = pintLocationID;
                voBinCache.BinID = pintBinID;

                //Set default values to object
                voBinCache.CommitQuantity = 0;
                voBinCache.DemanQuantity = 0;
                voBinCache.SupplyQuantity = 0;

                //call add method to add new
                dsBinCache.Add(voBinCache);
            }

            if (pstrLot.Length != 0)
            {
                dsBinCache.UpdateAddOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID, pstrLot, pdecQuantity);
            }
            else
            {
                dsBinCache.UpdateAddOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID, pdecQuantity);
            }

        }

        /// <param name="pdecQuantity">Quantity to add</param>
        //[AutoComplete(true)]
        public void UpdateSubtractOHQuantity(int pintCCNID, int pintMasterLocationID, int pintLocationID, int pintBinID, int pintProductID, decimal pdecQuantity, string pstrLot, string pstrSerial)
        {
            //validate data
            if (pstrLot == null) pstrLot = string.Empty;
            if (pstrSerial == null) pstrSerial = string.Empty;


            IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
            IV_LocationCacheDS dsLocCache = new IV_LocationCacheDS();
            IV_MasLocCacheDS dsMasLocCache = new IV_MasLocCacheDS();

            if (pstrLot.Length != 0 && pstrSerial.Length != 0 && pintBinID > 0)
            {
                //if it has both Bin, Lot and Serial
                dsBinCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID, pstrLot, pdecQuantity);
                dsLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pstrLot, pdecQuantity);
                dsMasLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintProductID, pstrLot, pdecQuantity);

                IV_ItemSerialDS dsItemSerial = new IV_ItemSerialDS();
                if (dsItemSerial.HasSerial(pstrSerial, pintCCNID))
                {
                    dsItemSerial.UpdateRemain(pstrSerial, pintCCNID, pintProductID, true);
                }
            }
            else if (pintBinID > 0 && pstrLot.Length != 0)
            {
                #region Check before subtract OHQuantity
                // HACK: SonHT
                IV_BinCacheVO voBinCache = new IV_BinCacheVO();
                voBinCache.CCNID = pintCCNID;
                voBinCache.MasterLocationID = pintMasterLocationID;
                voBinCache.LocationID = pintLocationID;
                voBinCache.BinID = pintBinID;
                voBinCache.ProductID = pintProductID;
                if (dsBinCache.GetOnhandQty(voBinCache) < pdecQuantity)
                {
                    throw new PCSBOException(ErrorCode.MESSAGE_AVAILABLE_WAS_USED_AFTER_POSTDATE, this.GetType().FullName + ".UpdateSubtractOHQuantity()", null);
                }

                #endregion
                //if it has both Bin and Lot
                dsBinCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID, pstrLot, pdecQuantity);
                dsLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pstrLot, pdecQuantity);
                dsMasLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintProductID, pstrLot, pdecQuantity);
            }
            else if (pintBinID > 0 && pstrLot.Length == 0 && pstrSerial.Length == 0)
            {
                #region Check before subtract OHQuantity
                // HACK: SonHT
                IV_BinCacheVO voBinCache = new IV_BinCacheVO();
                voBinCache.CCNID = pintCCNID;
                voBinCache.MasterLocationID = pintMasterLocationID;
                voBinCache.LocationID = pintLocationID;
                voBinCache.BinID = pintBinID;
                voBinCache.ProductID = pintProductID;
                if (dsBinCache.GetOnhandQty(voBinCache) < pdecQuantity)
                {
                    throw new PCSBOException(ErrorCode.MESSAGE_AVAILABLE_WAS_USED_AFTER_POSTDATE, this.GetType().FullName + ".UpdateSubtractOHQuantity()", null);
                }

                #endregion
                //if it has Bin and no Lot, no Serial
                dsBinCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID, pdecQuantity);
                dsLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity);
                dsMasLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity);
            }
            else if (pintLocationID > 0 && pintBinID <= 0 && pstrLot.Length == 0 && pstrSerial.Length == 0)
            {
                //if it has Loc and (no Lot, no Bin)
                dsLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity);
                dsMasLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity);
            }
            else if (pintLocationID > 0 && pstrLot.Length != 0 && pintBinID <= 0 && pstrSerial.Length == 0)
            {
                //if it has both Loc and Lot (no Bin)
                dsLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pstrLot, pdecQuantity);
                dsMasLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintProductID, pstrLot, pdecQuantity);
            }
            else if (pstrLot.Length != 0 && pstrSerial.Length != 0 && pintBinID <= 0)
            {
                //if it has Lot and Serial but no Bin
                dsLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pstrLot, pdecQuantity);
                dsMasLocCache.UpdateSubtractOHQuantity(pintCCNID, pintMasterLocationID, pintProductID, pstrLot, pdecQuantity);

                IV_ItemSerialDS dsItemSerial = new IV_ItemSerialDS();
                if (dsItemSerial.HasSerial(pstrSerial, pintCCNID))
                {
                    dsItemSerial.UpdateRemain(pstrSerial, pintCCNID, pintProductID, true);
                }
            }

        }

        /// <param name="pdecQuantity">Quantity to add</param>
        //[AutoComplete(true)]
        public void UpdateAddOHQuantity(int pintCCNID, int pintMasterLocationID, int pintLocationID, int pintBinID, int pintProductID, decimal pdecQuantity, string pstrLot, string pstrSerial)
        {

            //validate data
            if (pstrLot == null) pstrLot = string.Empty;
            if (pstrSerial == null) pstrSerial = string.Empty;

            if (pintBinID > 0)
            {
                // if it has Bin, Lot and Serial
                if (pstrLot.Length != 0 && pstrSerial.Length != 0)
                {
                    UpdateAddOHQuantityBin(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID, pdecQuantity, pstrLot);
                    UpdateAddOHQuantityLoc(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity, pstrLot);
                    UpdateAddOHQuantityMasLoc(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity, pstrLot);

                    IV_ItemSerialDS dsItemSerial = new IV_ItemSerialDS();
                    if (dsItemSerial.HasSerial(pstrSerial, pintCCNID))
                    {
                        dsItemSerial.UpdateRemain(pstrSerial, pintCCNID, pintProductID, true);
                    }
                    else
                    {
                        IV_ItemSerialVO voItemSerial = new IV_ItemSerialVO();
                        voItemSerial.BinID = pintBinID;
                        voItemSerial.CCNID = pintCCNID;
                        voItemSerial.LocationID = pintLocationID;
                        voItemSerial.MasterLocationID = pintMasterLocationID;
                        voItemSerial.ProductID = pintProductID;
                        voItemSerial.Serial = pstrSerial;
                        voItemSerial.Lot = pstrLot;
                        voItemSerial.Remain = true;
                        //TODO: Need to change based on business
                        voItemSerial.RefNo = 0;
                        voItemSerial.RefLine = 0;
                        dsItemSerial.Add(voItemSerial);
                    }
                }
                else
                {
                    //if has Bin and (dont has Lot or dont has Serial) 
                    UpdateAddOHQuantityBin(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID, pdecQuantity, pstrLot);
                    UpdateAddOHQuantityLoc(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity, pstrLot);
                    UpdateAddOHQuantityMasLoc(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity, pstrLot);
                }
            }
            else //Bin <= 0 
            {
                if (pstrLot.Length != 0 && pstrSerial.Length != 0)
                {
                    //if it has Lot and Serial but no Bin
                    UpdateAddOHQuantityLoc(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity, pstrLot);
                    UpdateAddOHQuantityMasLoc(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity, pstrLot);

                    IV_ItemSerialDS dsItemSerial = new IV_ItemSerialDS();
                    if (dsItemSerial.HasSerial(pstrSerial, pintCCNID))
                    {
                        dsItemSerial.UpdateRemain(pstrSerial, pintCCNID, pintProductID, true);
                    }
                    else
                    {
                        IV_ItemSerialVO voItemSerial = new IV_ItemSerialVO();
                        voItemSerial.BinID = pintBinID;
                        voItemSerial.CCNID = pintCCNID;
                        voItemSerial.LocationID = pintLocationID;
                        voItemSerial.MasterLocationID = pintMasterLocationID;
                        voItemSerial.ProductID = pintProductID;
                        voItemSerial.Serial = pstrSerial;
                        voItemSerial.Lot = pstrLot;
                        voItemSerial.Remain = true;

                        dsItemSerial.Add(voItemSerial);
                    }
                }
                else
                {
                    //if dont has Bin and (dont has Lot or dont has Serial) 
                    UpdateAddOHQuantityLoc(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity, pstrLot);
                    UpdateAddOHQuantityMasLoc(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity, pstrLot);
                }
            }

        }

        /// <param name="pdecQuantity">Quantity to add</param>
        //[AutoComplete(true)]
        public decimal CheckAvailableQuantity(int pintCCNID, int pintMasterLocationID, int pintLocationID, int pintBinID, int pintProductID, decimal pdecQuantity, string pstrLot, string pstrSerial)
        {

            //validate data
            if (pstrLot == null) pstrLot = string.Empty;
            if (pstrSerial == null) pstrSerial = string.Empty;

            decimal decQuantity = 0;
            //if it has Bin and has no Lot
            if (pintBinID > 0 && pstrLot.Length == 0)
            {
                IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
                decQuantity = dsBinCache.GetAvailableQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID);
                if (decQuantity >= pdecQuantity)
                {
                    return -1;
                }
                else
                {
                    return decQuantity;
                }
            }
            else if (pintBinID > 0 && pstrLot.Length != 0)
            {
                //if has both Bin and Lot
                IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
                decQuantity = dsBinCache.GetAvailableQuantityByLot(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pstrLot, pintProductID);
                if (decQuantity >= pdecQuantity)
                {
                    return -1;
                }
                else
                {
                    return decQuantity;
                }
            }
            else if (pintLocationID > 0 && pstrLot.Length != 0)
            {
                //if has both Bin and Lot
                IV_LocationCacheDS dsLocationCache = new IV_LocationCacheDS();
                decQuantity = dsLocationCache.GetAvailableQuantityByLot(pintCCNID, pintMasterLocationID, pintLocationID, pstrLot, pintProductID);
                if (decQuantity >= pdecQuantity)
                {
                    return -1;
                }
                else
                {
                    return decQuantity;
                }
            }
            else if (pintLocationID > 0 && pstrLot.Length == 0)
            {
                //if has both Bin and Lot
                IV_LocationCacheDS dsLocationCache = new IV_LocationCacheDS();
                decQuantity = dsLocationCache.GetAvailableQuantityByLocation(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID);
                if (decQuantity >= pdecQuantity)
                {
                    return -1;
                }
                else
                {
                    return decQuantity;
                }
            }
            else if (pintBinID > 0 && pstrLot.Length != 0 && pstrSerial.Length != 0)
            {
                //if has both Bin and Lot
                IV_ItemSerialDS dsItemSerial = new IV_ItemSerialDS();
                if (dsItemSerial.HasSerial(pstrSerial, pintCCNID))
                {
                    return -1;
                }
                else
                {
                    return 0;
                }
            }

            return -1;

        }
        /// <summary>
        ///  Get commit quantity base on BinID if BinID > 0 else base on LocID
        /// </summary>
        /// <param name="pdtmPostDate"></param>
        /// <param name="pintCCNID"></param>
        /// <param name="pintMasterLocationID"></param>
        /// <param name="pintLocationID"></param>
        /// <param name="pintBinID"></param>
        /// <param name="pintProductID"></param>
        /// <returns></returns>
        /// <author>Trada</author>
        /// <date>Monday, December 19 2005</date>
        //[AutoComplete(true)]
        public decimal GetCommitQtyByPostDate(DateTime pdtmPostDate, int pintCCNID, int pintMasterLocationID, int pintLocationID, int pintBinID, int pintProductID)
        {
            if (pintBinID > 0)
            {
                IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
                decimal decCommitQty = 0;
                if (pdtmPostDate < (new UtilsBO()).GetDBDate())
                {
                    decCommitQty = dsBinCache.GetCommitQtyByPostDate(pdtmPostDate, pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID);
                    return decCommitQty;
                }
                else
                {
                    decCommitQty = dsBinCache.GetCommitQtyByPostDate(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID);
                    return decCommitQty;
                }
            }
            else
            {
                IV_LocationCacheDS dsLocationCache = new IV_LocationCacheDS();
                decimal decCommitQty = 0;
                if (pdtmPostDate < (new UtilsBO()).GetDBDate())
                {
                    decCommitQty = dsLocationCache.GetCommitQtyByPostDate(pdtmPostDate, pintCCNID, pintMasterLocationID, pintLocationID, pintProductID);
                    return decCommitQty;
                }
                else
                {
                    decCommitQty = dsLocationCache.GetCommitQtyByPostDate(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID);
                    return decCommitQty;
                }
            }
        }
        /// <summary>
        /// GetAvailableQtyByPostDate
        /// </summary>
        /// <param name="pdtmPostDate"></param>
        /// <param name="pintCCNID"></param>
        /// <param name="pintMasterLocationID"></param>
        /// <param name="pintLocationID"></param>
        /// <param name="pintBinID"></param>
        /// <param name="pintProductID"></param>
        /// <returns></returns>
        /// <author>Trada</author>
        /// <date>Tuesday, December 20 2005</date>
        //[AutoComplete(true)]
        public decimal GetAvailableQtyByPostDate(DateTime pdtmPostDate, int pintCCNID, int pintMasterLocationID, int pintLocationID, int pintBinID, int pintProductID)
        {
            return GetOHQtyByPostDate(pdtmPostDate, pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID)
                - GetCommitQtyByPostDate(pdtmPostDate, pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID);
        }
        /// <summary>
        /// GetOHQtyByPostDate
        /// </summary>
        /// <param name="pdtmPostDate"></param>
        /// <param name="pintCCNID"></param>
        /// <param name="pintMasterLocationID"></param>
        /// <param name="pintLocationID"></param>
        /// <param name="pintBinID"></param>
        /// <param name="pintProductID"></param>
        /// <returns></returns>
        /// <author>Trada</author>
        /// <date>Tuesday, December 20 2005</date>
        //[AutoComplete(true)]
        public decimal GetOHQtyByPostDate(DateTime pdtmPostDate, int pintCCNID, int pintMasterLocationID, int pintLocationID, int pintBinID, int pintProductID)
        {
            if (pintBinID > 0)
            {
                IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
                decimal decCommitQty = 0;
                if (pdtmPostDate < (new UtilsBO()).GetDBDate())
                {
                    decCommitQty = dsBinCache.GetOHQtyByPostDate(pdtmPostDate, pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID);
                    return decCommitQty;
                }
                else
                {
                    decCommitQty = dsBinCache.GetOHQtyByPostDate(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID);
                    return decCommitQty;
                }
            }
            else
            {
                IV_LocationCacheDS dsLocationCache = new IV_LocationCacheDS();
                decimal decCommitQty = 0;
                if (pdtmPostDate < (new UtilsBO()).GetDBDate())
                {
                    decCommitQty = dsLocationCache.GetOHQtyByPostDate(pdtmPostDate, pintCCNID, pintMasterLocationID, pintLocationID, pintProductID);
                    return decCommitQty;
                }
                else
                {
                    decCommitQty = dsLocationCache.GetOHQtyByPostDate(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID);
                    return decCommitQty;
                }
            }

        }
        //[AutoComplete(true)]
        public DataTable GetOHQtyByPostDate(DateTime pdtmPostDate, int pintMasterLocationID, int pintLocationID, int pintBinID, int pintProductID)
        {
            IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
            if (pdtmPostDate < (new UtilsBO()).GetDBDate())
                return dsBinCache.GetOHQtyByPostDate(pdtmPostDate, pintMasterLocationID, pintLocationID, pintBinID, pintProductID);
            else
                return dsBinCache.GetOHQtyByPostDate(pintMasterLocationID, pintLocationID, pintBinID, pintProductID);
        }
        //[AutoComplete(true)]
        public DataSet ListAllBinCache()
        {
            IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
            return dsBinCache.ListAllBinCache();
        }
        //[AutoComplete(true)]
        public DataSet ListAllBinCache(int pintBinID)
        {
            IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
            return dsBinCache.ListAllBinCache(pintBinID);
        }
        //[AutoComplete(true)]
        public DataSet ListAllBinCacheWithProductInfo(int pintBinID)
        {
            IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
            return dsBinCache.ListAllBinCacheWithProductInfo(pintBinID);
        }
        //[AutoComplete(true)]
        public DataTable ListAllItem()
        {
            ITM_ProductDS dsProduct = new ITM_ProductDS();
            return dsProduct.ListForImport();
        }
        //[AutoComplete(true)]
        public DataSet ListAllLocationCache()
        {
            IV_LocationCacheDS dsLocCache = new IV_LocationCacheDS();
            return dsLocCache.ListAllCache();
        }
        //[AutoComplete(true)]
        public DataSet ListAllLocationCache(int pintLocationID)
        {
            IV_LocationCacheDS dsLocCache = new IV_LocationCacheDS();
            return dsLocCache.ListAllCache(pintLocationID);
        }
        //[AutoComplete(true)]
        public DataSet ListAllMasLocCache()
        {
            IV_MasLocCacheDS dsMas = new IV_MasLocCacheDS();
            return dsMas.ListAllCache();
        }
        //cuonglv
        public void UpdateSubstractCommitQtyAll(int iCCNID, int iMasterLocationID, int iLocationID, int iBinID, int iProductID, decimal decQty, string strLot, string strSerial, PCSDataContext db)
        {
            try
            {
                string strQty = decQty.ToString().Replace(",", ".");
                if (db == null) db = new PCSDataContext(Utils.Instance.ConnectionString);
                //Update OHQtyLoc
                StringBuilder strSql = new StringBuilder();

                strSql.Append(" UPDATE " + IV_LocationCacheTable.TABLE_NAME + " SET ");
                strSql.Append(IV_LocationCacheTable.COMMITQUANTITY_FLD + " = ISNULL(" + IV_LocationCacheTable.COMMITQUANTITY_FLD + ", 0)-   " + strQty);
                strSql.Append(" WHERE " + IV_LocationCacheTable.LOCATIONID_FLD + "= " + iLocationID.ToString());
                strSql.Append(" AND " + IV_LocationCacheTable.PRODUCTID_FLD + "= " + iProductID.ToString());
                strSql.Append(" AND " + IV_LocationCacheTable.CCNID_FLD + "= " + iCCNID.ToString());
                if (strLot.Length > 0)
                    strSql.Append(" AND " + IV_LocationCacheTable.LOT_FLD + "= " + strLot);
                strSql.Append(" AND " + IV_LocationCacheTable.MASTERLOCATIONID_FLD + "= " + iMasterLocationID.ToString());

                strSql.Append(" UPDATE " + IV_MasLocCacheTable.TABLE_NAME + " SET ");
                strSql.Append(IV_MasLocCacheTable.COMMITQUANTITY_FLD + "= ISNULL(" + IV_MasLocCacheTable.COMMITQUANTITY_FLD + ", 0) - " + strQty);
                strSql.Append(" WHERE " + IV_MasLocCacheTable.MASTERLOCATIONID_FLD + "= " + iMasterLocationID.ToString());
                strSql.Append(" AND " + IV_MasLocCacheTable.CCNID_FLD + "= " + iCCNID.ToString());
                if (strLot.Length > 0)
                    strSql.Append(" AND " + IV_MasLocCacheTable.LOT_FLD + "= " + strLot);
                strSql.Append(" AND " + IV_MasLocCacheTable.PRODUCTID_FLD + "= " + iProductID.ToString());
                //Update OHQtyBin
                if (iBinID != null && iBinID > 0)
                {
                    strSql.Append(" UPDATE " + IV_BinCacheTable.TABLE_NAME + " SET ");
                    strSql.Append(IV_BinCacheTable.COMMITQUANTITY_FLD + "= ISNULL(" + IV_BinCacheTable.COMMITQUANTITY_FLD + ", 0) - " + strQty);
                    strSql.Append(" WHERE " + IV_BinCacheTable.BINID_FLD + "= " + iBinID.ToString());
                    strSql.Append(" AND " + IV_BinCacheTable.CCNID_FLD + "= " + iCCNID.ToString());
                    strSql.Append(" AND " + IV_BinCacheTable.MASTERLOCATIONID_FLD + "= " + iMasterLocationID.ToString());
                    strSql.Append(" AND " + IV_BinCacheTable.LOCATIONID_FLD + "= " + iLocationID.ToString());
                    strSql.Append(" AND " + IV_BinCacheTable.PRODUCTID_FLD + "= " + iProductID.ToString());
                    if (strLot.Length > 0)
                        strSql.Append(" AND " + IV_BinCacheTable.LOT_FLD + "= " + strLot);
                }
                if (strSql.Length > 0)
                    db.ExecuteCommand(strSql.ToString());

            }
            catch (Exception ex) { throw ex; }
        }
        #region // HACK: DuongNA 2005-10-31
        //[AutoComplete(true)]
        public void UpdateSubtractCommitQuantity(int pintCCNID, int pintMasterLocationID, int pintLocationID, int pintBinID, int pintProductID, decimal pdecQuantity, string pstrLot, string pstrSerial)
        {

            //validate data
            if (pstrLot == null) pstrLot = string.Empty;
            if (pstrSerial == null) pstrSerial = string.Empty;


            IV_BinCacheDS dsBinCache = new IV_BinCacheDS();
            IV_LocationCacheDS dsLocCache = new IV_LocationCacheDS();
            IV_MasLocCacheDS dsMasLocCache = new IV_MasLocCacheDS();

            if (pstrLot.Length != 0 && pstrSerial.Length != 0 && pintBinID > 0)
            {
                //if it has both Bin, Lot and Serial
                dsBinCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID, pdecQuantity);
                dsLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity);
                dsMasLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity);

                /*IV_ItemSerialDS dsItemSerial = new IV_ItemSerialDS();
                if(dsItemSerial.HasSerial(pstrSerial, pintCCNID))
                {						
                    dsItemSerial.UpdateRemain(pstrSerial, pintCCNID, pintProductID, true);
                }*/
            }
            else if (pintBinID > 0 && pstrLot.Length != 0)
            {
                //if it has both Bin and Lot
                dsBinCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID, pdecQuantity);
                dsLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity);
                dsMasLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity);
            }
            else if (pintBinID > 0 && pstrLot.Length == 0 && pstrSerial.Length == 0)
            {
                //if it has Bin and no Lot, no Serial
                dsBinCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintBinID, pintProductID, pdecQuantity);
                dsLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity);
                dsMasLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity);
            }
            else if (pintLocationID > 0 && pintBinID <= 0 && pstrLot.Length == 0 && pstrSerial.Length == 0)
            {
                //if it has Loc and (no Lot, no Bin)
                dsLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity);
                dsMasLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity);
            }
            else if (pintLocationID > 0 && pstrLot.Length != 0 && pintBinID <= 0 && pstrSerial.Length == 0)
            {
                //if it has both Loc and Lot (no Bin)
                dsLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity);
                dsMasLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity);
            }
            else if (pstrLot.Length != 0 && pstrSerial.Length != 0 && pintBinID <= 0)
            {
                //if it has Lot and Serial but no Bin
                dsLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintLocationID, pintProductID, pdecQuantity);
                dsMasLocCache.UpdateSubtractCommitQuantity(pintCCNID, pintMasterLocationID, pintProductID, pdecQuantity);

                /*IV_ItemSerialDS dsItemSerial = new IV_ItemSerialDS();
                if(dsItemSerial.HasSerial(pstrSerial, pintCCNID))
                {						
                    dsItemSerial.UpdateRemain(pstrSerial, pintCCNID, pintProductID, true);
                }*/
            }

        }
        #endregion // END: DuongNA 2005-10-31

        #endregion Quantity Related Methods

        #region Transaction History Related Methods
        /// <summary>
        /// Prepare: 
        /// - Put Transaction Type as parameter (via Constants)
        /// - assign following properties of MST_TransactionVO: (for Master object only)
        /// + CCNID, MasterLocationID, LocationID (if have), BinID (if have)
        /// + Lot, Serial (if have)
        /// + RefMasterID
        /// + TransTypeID = MST_TransTypeDS.GetTranTypeID(TransactionType Code)
        /// + ProductID (if have).
        /// 
        /// 1. get master object via RefMasterID
        /// 2. get all detail data of Master object if any
        /// 3. foreach detail object
        /// 3.1 check transaction type
        /// 3.2 assign value associated with trans type
        /// 3.3 assign common value: On-hand quantity, cost
        /// 3.4 save to database
        /// </summary>
        /// <param name="pstrTransType">Transaction Type - from Constants</param>
        /// <param name="pobjTransactionHistoryVO">MST_TransactionHistoryVO. You need to input CCNID, TransDate, TransTypeID, MasterLocationID, RefMasterID</param>
        /// <param name="pintIssuePurposeID">Issue Purpose</param>
        //[AutoComplete(true)]
        public void SaveTransactionHis(string pstrTransType, int pintIssuePurposeID,
            MST_TransactionHistory voTransHis, PCSDataContext db, params string[] pstrComment)
        {
            using (var trans = new TransactionScope())
            {
                if (db == null) db = new PCSDataContext(Utils.Instance.ConnectionString);
                try
                {
                    //Assign transaction type ID
                    voTransHis.TranTypeID = db.MST_TranTypes.SingleOrDefault<MST_TranType>(e => e.Code == pstrTransType).TranTypeID;

                    //HACKED by Tuan TQ. 20 Dec, 2005. Set Transaction Date to current server date
                    voTransHis.IssuePurposeID = pintIssuePurposeID;

                    //Assign Transaction Comment
                    if (pstrComment != null && pstrComment.Length > 0)
                        voTransHis.Comment = pstrComment[0];
                    else
                        voTransHis.Comment = string.Empty;

                    // username
                    voTransHis.UserName = SystemProperty.UserName;

                    switch (pstrTransType)
                    {
                        default:
                            //Assign values
                            //AssignValueForInventory(voTransHis);
                            //Get product info
                            ITM_Product voProduct = db.ITM_Products.SingleOrDefault<ITM_Product>(e => e.ProductID == voTransHis.ProductID);

                            //Get WO Detail infor
                            //DataRow drowPODetail = dsCommon.GetWODetail(voTransHis.RefDetailID);
                            PRO_WorkOrderDetail objWO = db.PRO_WorkOrderDetails.SingleOrDefault<PRO_WorkOrderDetail>(e => e.WorkOrderDetailID == voTransHis.RefDetailID);

                            if (voProduct != null)
                            {
                                if (voProduct.CostMethod == (int)CostMethodEnum.AVG)
                                {
                                    voTransHis.NewAvgCost = objWO.EstCst;
                                }
                            }
                            //Re-assign TransactionHistory
                            AssignHistoryValue(voTransHis, db);
                            // 19-06-2006 dungla: refine quantity before save to database
                            if (voTransHis.BinOHQuantity < 0)
                                voTransHis.BinOHQuantity = 0;
                            if (voTransHis.LocationOHQuantity < 0)
                                voTransHis.LocationOHQuantity = 0;
                            if (voTransHis.MasLocOHQuantity < 0)
                                voTransHis.MasLocOHQuantity = 0;
                            // Cal Add method of Transaction History DS to save to database			
                            db.MST_TransactionHistories.InsertOnSubmit(voTransHis);
                            break;
                    }
                    db.SubmitChanges();
                }
                catch (PCSDBException ex)
                {
                    Transaction.Current.Rollback();
                    throw ex;
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message, ex);
                }
                finally { trans.Complete(); }
            }

        }
        public void SaveTransactionHistory(string pstrTransType, int pintIssuePurposeID,
            object pobjTransactionHistoryVO, params string[] pstrComment)
        {
            try
            {
                MST_TransactionHistoryVO voTransHis = (MST_TransactionHistoryVO)pobjTransactionHistoryVO;
                MST_TransactionHistoryDS dsTransHis = new MST_TransactionHistoryDS();
                DataTable dtbItem = null;

                //Assign transaction type ID
                voTransHis.TranTypeID = (new MST_TranTypeDS()).GetTranTypeID(pstrTransType);

                //HACKED by Tuan TQ. 20 Dec, 2005. Set Transaction Date to current server date
                voTransHis.TransDate = (new UtilsDS()).GetDBDate();
                voTransHis.PurposeID = pintIssuePurposeID;

                //Assign Transaction Comment
                if (pstrComment != null && pstrComment.Length > 0)
                    voTransHis.Comment = pstrComment[0];
                else
                    voTransHis.Comment = string.Empty;

                // username
                voTransHis.Username = SystemProperty.UserName;

                switch (pstrTransType)
                {
                    default:
                        //Assign values
                        AssignValueForInventory(voTransHis);
                        AssignCommonValue(voTransHis);
                        // 19-06-2006 dungla: refine quantity before save to database
                        if (voTransHis.BinOHQuantity < 0)
                            voTransHis.BinOHQuantity = 0;
                        if (voTransHis.LocationOHQuantity < 0)
                            voTransHis.LocationOHQuantity = 0;
                        if (voTransHis.MasLocOHQuantity < 0)
                            voTransHis.MasLocOHQuantity = 0;
                        // Cal Add method of Transaction History DS to save to database			
                        dsTransHis.Add(voTransHis);
                        break;
                }
            }
            catch (PCSDBException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
        }


        //[AutoComplete(true)]
        public void UpdateTransactionHistory(string pstrTransType,
            int pintIssuePurposeID, object pobjTransactionHistoryVO, params string[] pstrComment)
        {
            try
            {
                MST_TransactionHistoryVO voTransHis = (MST_TransactionHistoryVO)pobjTransactionHistoryVO;
                MST_TransactionHistoryDS dsTransHis = new MST_TransactionHistoryDS();

                //Assign transaction type ID
                voTransHis.TranTypeID = (new MST_TranTypeDS()).GetTranTypeID(pstrTransType);

                //Assign Transaction Comment
                if (pstrComment != null && pstrComment.Length > 0)
                    voTransHis.Comment = pstrComment[0];
                else
                    voTransHis.Comment = string.Empty;

                //HACKED by Tuan TQ. 20 Dec, 2005. Set Transaction Date to current server date
                voTransHis.TransDate = (new UtilsDS()).GetDBDate();
                voTransHis.PurposeID = pintIssuePurposeID;

                // username
                voTransHis.Username = SystemProperty.UserName;

                switch (pstrTransType)
                {
                    default:
                        // 19-06-2006 dungla: refine quantity before save to database
                        AssignValueForInventory(voTransHis);
                        AssignCommonValue(voTransHis);

                        if (voTransHis.BinOHQuantity < 0)
                            voTransHis.BinOHQuantity = 0;
                        if (voTransHis.LocationOHQuantity < 0)
                            voTransHis.LocationOHQuantity = 0;
                        if (voTransHis.MasLocOHQuantity < 0)
                            voTransHis.MasLocOHQuantity = 0;

                        // Cal Add method of Transaction History DS to save to database		
                        dsTransHis.UpdatebyRefMasterID(voTransHis);
                        break;
                }
            }
            catch (PCSDBException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message, ex);
            }
        }

        /// <summary>
        /// Need to convert UM to StockUMID
        /// 
        /// 1. Prepare: Retrieve ITM_ProductVO, PO_PurchaseOrderReceiptMasterVO, PO_PurchaseOrderReceiptDetailVO value object from database based on ID from MST_TransactionHistoryVO.
        /// If PO_PurchaseOrderReceiptMasterVO.PurchaseOrderMasterID > 0
        /// - Retrieve PO_PurchaseOrderMasterVO from ID
        /// If PO_PurchaseOrderReceiptDetailVO.PurchaseOrderDetailID > 0
        /// - Retrieve PO_PurchaseOrderDetailVO from ID
        /// 
        /// 2. PartyID, PartyLocationID, CurrencyID, ExchangeRate from Purchase Order Master
        /// If PO_PurchaseOrderMasterVO != null
        /// - MST_TransactionHistoryVO.PartyID = PO_PurchaseOrderMasterVO.PartyID
        /// - MST_TransactionHistoryVO.PartyLocationID = PO_PurchaseOrderMasterVO.VendorLocID
        /// - MST_TransactionHistoryVO.CurrencyID = PO_PurchaseOrderMasterVO.CurrencyID
        /// - MST_TransactionHistoryVO.ExchangeRate = PO_PurchaseOrderMasterVO.ExchangeRate
        /// 
        /// 3. If PO_PurchaseOrderReceiptDetailVO != null
        /// - MST_TransactionHistoryVO.Lot = PO_PurchaseOrderReceiptDetailVO.Lot
        /// - MST_TransactionHistoryVO.Serial = PO_PurchaseOrderReceiptDetailVO.Serial
        /// 
        /// 4. If ITM_ProductVO != null and ITM_ProductVO.CostMethod = CostMethodEnum.AVG (Average Cost)
        /// - MST_TransactionHistoryVO.OldAvgCost = MST_TransactionHistoryVO.Cost
        /// - MST_TransactionHistoryVO.NewAvgCost = 
        /// ((IV_MasLocCache.OHQuantity * IV_MasLocCache.AvgCost) + (MST_TransactionHistoryVO.Quantity * PO_PurchaseOrderDetailVO.UnitPrice)) / (IV_MasLocCache.OHQuantity + MST_TransactionHistoryVO.Quantity)
        /// </summary>
        /// <param name="pobjTransactionHistory">MST_TransactionHistoryVO</param>
        //[AutoComplete(true)]
        public void AssignValueForPOReceipt(object pobjTransactionHistory)
        {
            decimal dUnitPrice = 0;
            MST_TransactionHistoryVO voTransHis = (MST_TransactionHistoryVO)pobjTransactionHistory;
            //Get product info
            ITM_Product voProduct = new ProductItemInfoBO().GetProductInfo(voTransHis.ProductID);

            //Get PO Receipt Master infor
            DataRow drowPOMaster = null;
            DataRow drowPODetail = null;

            //DataRow drowPOReceiptMaster = dsCommon.GetPOReceiptMaster(voTransHis.RefMasterID);
            DataRow drowPOReceiptDetail = dsCommon.GetPOReceiptDetail(voTransHis.RefDetailID);

            //If PO_PurchaseOrderReceiptMasterVO.PurchaseOrderMasterID > 0,
            //Retrieve PO_PurchaseOrderMasterVO from ID
            if (drowPOReceiptDetail != null)
            {
                if (drowPOReceiptDetail[PO_PurchaseOrderReceiptDetailTable.PURCHASEORDERMASTERID_FLD] != null &&
                    drowPOReceiptDetail[PO_PurchaseOrderReceiptDetailTable.PURCHASEORDERMASTERID_FLD] != DBNull.Value)
                {
                    int intPOMasterID = 0;
                    try
                    {
                        intPOMasterID = int.Parse(drowPOReceiptDetail[PO_PurchaseOrderReceiptDetailTable.PURCHASEORDERMASTERID_FLD].ToString());
                    }
                    catch { }
                    drowPOMaster = dsCommon.GetPOMaster(intPOMasterID);
                }
            }

            //If PO_PurchaseOrderReceiptDetailVO.PurchaseOrderDetailID > 0
            //Retrieve PO_PurchaseOrderDetailVO from ID
            if (drowPOReceiptDetail != null)
            {
                if (drowPOReceiptDetail[PO_PurchaseOrderReceiptDetailTable.PURCHASEORDERRECEIPTDETAILID_FLD] != null &&
                    drowPOReceiptDetail[PO_PurchaseOrderReceiptDetailTable.PURCHASEORDERRECEIPTDETAILID_FLD] != DBNull.Value)
                {
                    int intPODetailID = 0;
                    try
                    {
                        intPODetailID = int.Parse(drowPOReceiptDetail[PO_PurchaseOrderReceiptDetailTable.PURCHASEORDERDETAILID_FLD].ToString());
                    }
                    catch { }
                    drowPODetail = dsCommon.GetPODetail(intPODetailID);
                    //Get unit price of this product
                    if (drowPODetail != null)
                    {
                        try
                        {
                            dUnitPrice = decimal.Parse(drowPODetail[PO_PurchaseOrderDetailTable.UNITPRICE_FLD].ToString());
                        }
                        catch { }
                    }
                }
            }

            //Set PartyID, PartyLocationID, CurrencyID, ExchangeRate from Purchase Order Master to Trans History				
            if (drowPOMaster != null)
            {
                try
                {
                    voTransHis.PartyID = int.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.PARTYID_FLD].ToString());
                }
                catch { }
                try
                {
                    voTransHis.PartyLocationID = int.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.VENDORLOCID_FLD].ToString());
                }
                catch { }
                try
                {
                    voTransHis.CurrencyID = int.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.CURRENCYID_FLD].ToString());
                }
                catch { }
                try
                {
                    voTransHis.ExchangeRate = decimal.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.EXCHANGERATE_FLD].ToString());
                }
                catch { }
            }

            //Set value to Trans History If PO_PurchaseOrderReceiptDetailVO != null
            //MST_TransactionHistoryVO.Lot = PO_PurchaseOrderReceiptDetailVO.Lot
            //MST_TransactionHistoryVO.Serial = PO_PurchaseOrderReceiptDetailVO.Serial
            if (drowPOReceiptDetail != null)
            {
                voTransHis.Lot = drowPOReceiptDetail[PO_PurchaseOrderReceiptDetailTable.LOT_FLD].ToString();
                voTransHis.Serial = drowPOReceiptDetail[PO_PurchaseOrderReceiptDetailTable.SERIAL_FLD].ToString();
            }

            /// 4. If ITM_ProductVO != null and ITM_ProductVO.CostMethod = CostMethodEnum.AVG (Average Cost)
            /// - MST_TransactionHistoryVO.OldAvgCost = MST_TransactionHistoryVO.Cost
            /// - MST_TransactionHistoryVO.NewAvgCost = 
            /// ((IV_MasLocCache.OHQuantity * IV_MasLocCache.AvgCost) + (MST_TransactionHistoryVO.Quantity * PO_PurchaseOrderDetailVO.UnitPrice)) / (IV_MasLocCache.OHQuantity + MST_TransactionHistoryVO.Quantity)
            if (voProduct != null)
            {
                if (voProduct.CostMethod == (int)CostMethodEnum.AVG)
                {
                    voTransHis.OldAvgCost = voTransHis.Cost;
                    //Get masloc cache
                    IV_MasLocCacheVO voMasLocCache = (IV_MasLocCacheVO)(new IV_MasLocCacheDS()).GetObjectVO(voTransHis.MasterLocationID, voProduct.ProductID, voTransHis.CCNID);
                    if (voMasLocCache != null)
                    {
                        voTransHis.NewAvgCost = (voMasLocCache.OHQuantity * voMasLocCache.AVGCost)
                            + (voTransHis.Quantity * dUnitPrice) / (voMasLocCache.OHQuantity + voTransHis.Quantity);
                    }
                }
            }

            //Re-assign TransactionHistory
            pobjTransactionHistory = voTransHis;
        }

        /// <summary>
        /// 1. Prepare: Retrieve ITM_ProductVO, SO_SaleOrderMasterVO, SO_SaleOrderDetailVO, SO_ReturnedGoodsMasterVO, SO_ReturnedGoodsDetailVO value object from database based on ID from MST_TransactionHistoryVO.
        /// 
        /// 2. PartyID, PartyLocationID retrieve from SO_ReturnedGoodsMasterVO
        /// 3. ExchangeRate, CurrencyID retrieve from SO_SaleOrderMasterVO
        /// 
        /// 4. If ITM_ProductVO != null and ITM_ProductVO.CostMethod = CostMethodEnum.AVG (Average Cost)
        /// - MST_TransactionHistoryVO.OldAvgCost = MST_TransactionHistoryVO.Cost
        /// - MST_TransactionHistoryVO.NewAvgCost = 
        /// ((IV_MasLocCache.OHQuantity * IV_MasLocCache.AvgCost) + (MST_TransactionHistoryVO.Quantity * SO_DetailCommitment.StdCost)) / (IV_MasLocCache.OHQuantity + MST_TransactionHistoryVO.Quantity)
        /// </summary>
        /// <param name="pobjTransactionHistory">MST_TransactionHistoryVO</param>
        //[AutoComplete(true)]
        public void AssignValueForRGReceive(object pobjTransactionHistory)
        {
            decimal dStdCost = 0;
            MST_TransactionHistoryVO voTransHis = (MST_TransactionHistoryVO)pobjTransactionHistory;
            //Get product info
            ITM_Product voProduct = new ProductItemInfoBO().GetProductInfo(voTransHis.ProductID);

            //Get SO Receipt Master infor
            DataRow drowSOMaster = null;

            DataRow drowSOReturnMaster = dsCommon.GetSOReturnGoodsMaster(voTransHis.RefMasterID);
            DataRow drowSOCommitDetail = dsCommon.GetSOCommitDetail(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.ProductID);

            //If SO_ReturnGoodsMasterVO.SalerOrderMasterID > 0,
            //Retrieve SO_SaleOrderMasterVO from ID
            if (drowSOReturnMaster != null)
            {
                if (drowSOReturnMaster[SO_ReturnedGoodsMasterTable.SALEORDERMASTERID_FLD].ToString() != string.Empty)
                {
                    drowSOMaster = dsCommon.GetSOMaster(int.Parse(drowSOReturnMaster[SO_ReturnedGoodsMasterTable.SALEORDERMASTERID_FLD].ToString()));
                }
            }
            //PartyID, PartyLocationID retrieve from SO_ReturnedGoodsMasterVO
            if (drowSOReturnMaster != null)
            {
                try
                {
                    voTransHis.PartyID = int.Parse(drowSOReturnMaster[SO_ReturnedGoodsMasterTable.PARTYID_FLD].ToString());
                }
                catch { }
                try
                {
                    voTransHis.PartyLocationID = int.Parse(drowSOReturnMaster[SO_ReturnedGoodsMasterTable.PARTYLOCATIONID_FLD].ToString());
                }
                catch { }
            }

            //ExchangeRate, CurrencyID retrieve from SO_SaleOrderMasterVO
            if (drowSOMaster != null)
            {
                try
                {
                    voTransHis.CurrencyID = int.Parse(drowSOMaster[SO_SaleOrderMasterTable.CURRENCYID_FLD].ToString());
                }
                catch { }
                try
                {
                    voTransHis.ExchangeRate = decimal.Parse(drowSOMaster[SO_SaleOrderMasterTable.EXCHANGERATE_FLD].ToString());
                }
                catch { }
            }

            // 4. If ITM_ProductVO != null and ITM_ProductVO.CostMethod = CostMethodEnum.AVG (Average Cost)
            // - MST_TransactionHistoryVO.OldAvgCost = MST_TransactionHistoryVO.Cost
            // - MST_TransactionHistoryVO.NewAvgCost = 
            // ((IV_MasLocCache.OHQuantity * IV_MasLocCache.AvgCost) + (MST_TransactionHistoryVO.Quantity * SO_DetailCommitment.StdCost)) / (IV_MasLocCache.OHQuantity + MST_TransactionHistoryVO.Quantity)
            if (voProduct != null)
            {
                if (voProduct.CostMethod == (int)CostMethodEnum.AVG)
                {
                    voTransHis.OldAvgCost = voTransHis.Cost;
                    //Get masloc cache
                    IV_MasLocCacheVO voMasLocCache = (IV_MasLocCacheVO)(new IV_MasLocCacheDS()).GetObjectVO(voTransHis.MasterLocationID, voProduct.ProductID, voTransHis.CCNID);

                    if (voMasLocCache != null & drowSOCommitDetail != null)
                    {
                        try
                        {
                            dStdCost = decimal.Parse(drowSOCommitDetail[SO_CommitInventoryDetailTable.STDCOST_FLD].ToString());
                        }
                        catch { }
                        try
                        {
                            voTransHis.NewAvgCost = (voMasLocCache.OHQuantity * voMasLocCache.AVGCost)
                                + (voTransHis.Quantity * dStdCost) / (voMasLocCache.OHQuantity + voTransHis.Quantity);
                        }
                        catch { }
                    }
                }
            }

            //Re-assign TransactionHistory
            pobjTransactionHistory = voTransHis;
        }

        /// <summary>
        /// 1. Prepare: Retrieve ITM_ProductVO, PO_PurchaseOderMasterVO, PO_PurchaseOderDetailVO, 
        ///	 PO_ReturnToVendorMasterVO, PO_ReturnToVendorDetailVO  value object from database based on ID from MST_TransactionHistoryVO.
        /// 
        /// 2. PartyID, PartyLocationID retrieve from PO_ReturnToVendorMasterVO
        /// 3. ExchangeRate, CurrencyID retrieve from PO_PurchaseOderMasterVO
        /// 
        /// 4. If ITM_ProductVO != null and ITM_ProductVO.CostMethod = CostMethodEnum.AVG (Average Cost)
        /// - MST_TransactionHistoryVO.OldAvgCost = MST_TransactionHistoryVO.Cost
        /// - MST_TransactionHistoryVO.NewAvgCost = 
        /// ((IV_MasLocCache.OHQuantity * IV_MasLocCache.AvgCost) + (MST_TransactionHistoryVO.Quantity * PO_PurchaseOrderDetailVO.UnitPrice)) / (IV_MasLocCache.OHQuantity + MST_TransactionHistoryVO.Quantity)
        /// </summary>
        /// <param name="pobjTransactionHistory">MST_TransactionHistoryVO</param>
        //[AutoComplete(true)]
        public void AssignValueForRTV(object pobjTransactionHistory)
        {
            decimal dUnitPrice = 0;
            MST_TransactionHistoryVO voTransHis = (MST_TransactionHistoryVO)pobjTransactionHistory;
            //Get product info
            ITM_Product voProduct = new ProductItemInfoBO().GetProductInfo(voTransHis.ProductID);

            //Get SO Receipt Master infor
            DataRow drowPOMaster = null;
            DataRow drowPODetail = null;

            DataRow drowPOReturn2VendorMaster = dsCommon.GetPOReturnToVendorMaster(voTransHis.RefMasterID);
            DataRow drowPOReturn2VendorDetail = dsCommon.GetPOReturnToVendorDetail(voTransHis.RefDetailID);

            //If PO_Return2Vendor not null, get PO_PurchaseOrderMaster, PO_PurchaseOrderDetail
            if (drowPOReturn2VendorMaster != null)
            {
                if (drowPOReturn2VendorMaster[PO_ReturnToVendorMasterTable.PURCHASEORDERMASTERID_FLD] != null)
                {
                    drowPOMaster = dsCommon.GetPOMaster(int.Parse(drowPOReturn2VendorMaster[PO_ReturnToVendorMasterTable.PURCHASEORDERMASTERID_FLD].ToString()));
                    drowPODetail = dsCommon.GetPODetail(int.Parse(drowPOReturn2VendorMaster[PO_ReturnToVendorMasterTable.PURCHASEORDERMASTERID_FLD].ToString()), voTransHis.ProductID);
                }
                if (drowPODetail != null)
                {
                    try
                    {
                        dUnitPrice = decimal.Parse(drowPODetail[PO_PurchaseOrderDetailTable.UNITPRICE_FLD].ToString());
                    }
                    catch { }
                }
            }

            //PartyID, PartyLocationID, ExchangeRate, CurrencyID retrieve from PO_PurchaseOrder
            if (drowPOMaster != null)
            {
                try
                {
                    voTransHis.PartyID = int.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.PARTYID_FLD].ToString());
                }
                catch { }
                try
                {
                    voTransHis.PartyLocationID = int.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.VENDORLOCID_FLD].ToString());
                }
                catch { }

                try
                {
                    voTransHis.CurrencyID = int.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.CURRENCYID_FLD].ToString());
                }
                catch { }
                if (!drowPOMaster[PO_PurchaseOrderMasterTable.EXCHANGERATE_FLD].Equals(DBNull.Value) && drowPOMaster[PO_PurchaseOrderMasterTable.EXCHANGERATE_FLD].ToString().Trim() != string.Empty)
                    voTransHis.ExchangeRate = decimal.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.EXCHANGERATE_FLD].ToString());
            }

            // 4. If ITM_ProductVO != null and ITM_ProductVO.CostMethod = CostMethodEnum.AVG (Average Cost)
            // - MST_TransactionHistoryVO.OldAvgCost = MST_TransactionHistoryVO.Cost
            // - MST_TransactionHistoryVO.NewAvgCost = 
            // ((IV_MasLocCache.OHQuantity * IV_MasLocCache.AvgCost) + (MST_TransactionHistoryVO.Quantity * PO_PurchaseOrderDetailVO.UnitPrice)) / (IV_MasLocCache.OHQuantity + MST_TransactionHistoryVO.Quantity)
            if (voProduct != null)
            {
                if (voProduct.CostMethod == (int)CostMethodEnum.AVG)
                {
                    voTransHis.OldAvgCost = voTransHis.Cost;
                    //Get masloc cache
                    IV_MasLocCacheVO voMasLocCache = (IV_MasLocCacheVO)(new IV_MasLocCacheDS()).GetObjectVO(voTransHis.MasterLocationID, voProduct.ProductID, voTransHis.CCNID);

                    if (voMasLocCache != null)
                    {
                        try
                        {
                            voTransHis.NewAvgCost = (voMasLocCache.OHQuantity * voMasLocCache.AVGCost)
                            + (voTransHis.Quantity * dUnitPrice) / (voMasLocCache.OHQuantity + voTransHis.Quantity);
                        }
                        catch { }
                    }
                }
            }

            //Re-assign TransactionHistory
            pobjTransactionHistory = voTransHis;
        }

        /// <summary>
        /// 1. Prepare: Retrieve ITM_ProductVO, MasterVO, DetailVO(if any) value object from database based on ID from MST_TransactionHistoryVO.
        /// 
        /// 2. PartyID, PartyLocationID = 0
        /// 3. ExchangeRate, CurrencyID = 0
        /// 
        /// 4. 
        /// - MST_TransactionHistoryVO.OldAvgCost = 0
        /// 4.1 If TransType is Work Order Complettion and ITM_Product.CostMethod = CostMethod.AVG
        /// - MST_TransactionHistoryVO.NewAvgCost =  WorkOrderDetail.EstCost
        /// </summary>
        /// <param name="pobjTransactionHistory">MST_TransactionHistoryVO</param>
        //[AutoComplete(true)]
        public void AssignValueForInventory(object pobjTransactionHistory)
        {
            decimal dEstimateCost = 0;
            MST_TransactionHistoryVO voTransHis = (MST_TransactionHistoryVO)pobjTransactionHistory;
            //Get product info
            ITM_Product voProduct = new ProductItemInfoBO().GetProductInfo(voTransHis.ProductID);

            //Get WO Detail infor
            DataRow drowPODetail = dsCommon.GetWODetail(voTransHis.RefDetailID);
            if (drowPODetail != null)
            {
                try
                {
                    dEstimateCost = decimal.Parse(drowPODetail[PRO_WorkOrderDetailTable.ESTCST_FLD].ToString());
                }
                catch { }
            }

            //HACKED -- Rem by Tuan TQ: fix error 3205 for Tuan DM. 27 Dec, 2005.
            //voTransHis.PartyID = 0;
            //voTransHis.PartyLocationID = 0;
            //voTransHis.CurrencyID = 0;
            //voTransHis.ExchangeRate = 0;
            //voTransHis.OldAvgCost = 0;
            //End hacked

            //If TransType is Work Order Complettion and ITM_Product.CostMethod = CostMethod.AVG
            //MST_TransactionHistoryVO.NewAvgCost =  WorkOrderDetail.EstCost
            if (voProduct != null)
            {
                if (voProduct.CostMethod == (int)CostMethodEnum.AVG)
                {
                    voTransHis.NewAvgCost = dEstimateCost;
                }
            }

            //Re-assign TransactionHistory
            pobjTransactionHistory = voTransHis;
        }

        /// <summary>
        /// 1. Prepare: Retrieve ITM_ProductVO, PO_PurchaseOderMasterVO, 
        ///	   PO_PurchaseOderDetailVO, PO_ReturnToVendorMasterVO, 
        ///	   PO_ReturnToVendorDetailVO  value object from database based on ID from MST_TransactionHistoryVO.
        /// 
        /// 2. PartyID, PartyLocationID retrieve from PO_ReturnToVendorMasterVO
        /// 3. ExchangeRate, CurrencyID retrieve from PO_PurchaseOderMasterVO
        /// 
        /// 4. If ITM_ProductVO != null and ITM_ProductVO.CostMethod = CostMethodEnum.AVG (Average Cost)
        /// - MST_TransactionHistoryVO.OldAvgCost = MST_TransactionHistoryVO.Cost
        /// - MST_TransactionHistoryVO.NewAvgCost = 
        /// ((IV_MasLocCache.OHQuantity * IV_MasLocCache.AvgCost) + (MST_TransactionHistoryVO.Quantity * PO_PurchaseOrderDetailVO.UnitPrice))
        ///  / (IV_MasLocCache.OHQuantity + MST_TransactionHistoryVO.Quantity)
        /// 
        /// 5. If PO_PurchaseOderDetailVO != null
        /// - MST_TransactionHistoryVO.BuySellCost = PO_PurchaseOderDetailVO.UnitPrice
        /// </summary>
        /// <param name="pobTransactionHistory">MST_TransactionHistoryVO</param>
        //[AutoComplete(true)]
        public void AssignValueForConfirmShipment(object pobjTransactionHistory)
        {
            decimal dUnitPrice = 0;
            MST_TransactionHistoryVO voTransHis = (MST_TransactionHistoryVO)pobjTransactionHistory;
            //Get product info
            ITM_Product voProduct = new ProductItemInfoBO().GetProductInfo(voTransHis.ProductID);

            //Get SO Receipt Master infor
            DataRow drowPOMaster = null;
            DataRow drowPODetail = null;

            DataRow drowPOReturn2VendorMaster = dsCommon.GetPOReturnToVendorMaster(voTransHis.RefMasterID);
            DataRow drowPOReturn2VendorDetail = dsCommon.GetPOReturnToVendorDetail(voTransHis.RefDetailID);

            //If PO_Return2Vendor not null, get PO_PurchaseOrderMaster, PO_PurchaseOrderDetail
            if (drowPOReturn2VendorMaster != null)
            {
                if (drowPOReturn2VendorMaster[PO_ReturnToVendorMasterTable.PURCHASEORDERMASTERID_FLD] != null)
                {
                    drowPOMaster = dsCommon.GetPOMaster(int.Parse(drowPOReturn2VendorMaster[PO_ReturnToVendorMasterTable.PURCHASEORDERMASTERID_FLD].ToString()));
                    drowPODetail = dsCommon.GetPODetail(int.Parse(drowPOReturn2VendorMaster[PO_ReturnToVendorMasterTable.PURCHASEORDERMASTERID_FLD].ToString()), voTransHis.ProductID);
                }
                if (drowPODetail != null)
                {
                    try
                    {
                        dUnitPrice = decimal.Parse(drowPODetail[PO_PurchaseOrderDetailTable.UNITPRICE_FLD].ToString());
                    }
                    catch { }
                }
            }

            //PartyID, PartyLocationID, ExchangeRate, CurrencyID retrieve from PO_PurchaseOrder
            if (drowPOMaster != null)
            {
                try
                {
                    voTransHis.PartyID = int.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.PARTYID_FLD].ToString());
                }
                catch { }
                try
                {
                    voTransHis.PartyLocationID = int.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.VENDORLOCID_FLD].ToString());
                }
                catch { }

                try
                {
                    voTransHis.CurrencyID = int.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.CURRENCYID_FLD].ToString());
                }
                catch { }
                try
                {
                    voTransHis.ExchangeRate = decimal.Parse(drowPOMaster[PO_PurchaseOrderMasterTable.EXCHANGERATE_FLD].ToString());
                }
                catch { }
            }

            // 4. If ITM_ProductVO != null and ITM_ProductVO.CostMethod = CostMethodEnum.AVG (Average Cost)
            // - MST_TransactionHistoryVO.OldAvgCost = MST_TransactionHistoryVO.Cost
            // - MST_TransactionHistoryVO.NewAvgCost = 
            // ((IV_MasLocCache.OHQuantity * IV_MasLocCache.AvgCost) + (MST_TransactionHistoryVO.Quantity * PO_PurchaseOrderDetailVO.UnitPrice)) / (IV_MasLocCache.OHQuantity + MST_TransactionHistoryVO.Quantity)
            if (voProduct != null)
            {
                if (voProduct.CostMethod == (int)CostMethodEnum.AVG)
                {
                    voTransHis.OldAvgCost = voTransHis.Cost;
                    //Get masloc cache
                    IV_MasLocCacheVO voMasLocCache = (IV_MasLocCacheVO)(new IV_MasLocCacheDS()).GetObjectVO(voTransHis.MasterLocationID, voProduct.ProductID, voTransHis.CCNID);

                    if (voMasLocCache != null)
                    {
                        try
                        {
                            voTransHis.NewAvgCost = (voMasLocCache.OHQuantity * voMasLocCache.AVGCost)
                            + (voTransHis.Quantity * dUnitPrice) / (voMasLocCache.OHQuantity + voTransHis.Quantity);
                        }
                        catch { }
                    }
                }
            }

            //5. If PO_PurchaseOderDetailVO != null
            //MST_TransactionHistoryVO.BuySellCost = PO_PurchaseOderDetailVO.UnitPrice
            voTransHis.BuySellCost = dUnitPrice;

            //Re-assign TransactionHistory
            pobjTransactionHistory = voTransHis;
        }

        /// <summary>
        /// Assign common value for all transaction: On-hand quantity and cost
        /// 
        /// 1. MasLocOHQuantity
        /// - If MST_TransactionHistoryVO.Lot != null: MST_TransactionHistoryVO.MasLocOHQuantity = IV_MasterLocationCacheDS.GetQuantityOnHandByLot(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.ProductID, MST_TransactionHistoryVO.Lot)
        /// - Else MST_TransactionHistoryVO.MasLocOHQuantity = IV_MasterLocationCacheDS.GetQuantityOnHand(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.ProductID)
        /// 
        /// 2. LocationOHQuantity
        /// If MST_TransactionHistoryVO.LocationID > 0
        /// - If MST_TransactionHistoryVO.Lot != null: MST_TransactionHistoryVO.LocationOHQuantity = IV_LocationCacheDS.GetQuantityOnHandByLot(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.ProductID, MST_TransactionHistoryVO.Lot)
        /// - Else MST_TransactionHistoryVO.LocationOHQuantity = IV_LocationCacheDS.GetQuantityOnHand(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.ProductID)
        /// 
        /// 3. BinOHQuantity
        /// If MST_TransactionHistoryVO.BinID > 0
        /// - If MST_TransactionHistoryVO.Lot != null: MST_TransactionHistoryVO.BinOHQuantity = IV_BinCacheDS.GetQuantityOnHandByLot(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.BinID, MST_TransactionHistoryVO.ProductID, MST_TransactionHistoryVO.Lot)
        /// - Else MST_TransactionHistoryVO.BinOHQuantity = IV_BinCacheDS.GetQuantityOnHand(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.BinID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.ProductID)
        /// 
        /// 4. Cost
        /// If ProductID > 0
        /// MST_TransactionHistoryVO.Cost = ITM_CostDS.GetItemCostTotalAmount21ByProductIDCCNID(pintProductID, pintCCNID)
        /// </summary>
        //[AutoComplete(true)]
        public void AssignHistoryValue(MST_TransactionHistory voTransHis, PCSDataContext db)
        {
            using (var trans = new TransactionScope())
            {
                if (db == null) db = new PCSDataContext(Utils.Instance.ConnectionString);
                try
                {
                    //1. MasLocOHQuantity
                    //- If MST_TransactionHistoryVO.Lot != null: MST_TransactionHistoryVO.MasLocOHQuantity = IV_MasterLocationCacheDS.GetQuantityOnHandByLot(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.ProductID, MST_TransactionHistoryVO.Lot)
                    //- Else MST_TransactionHistoryVO.MasLocOHQuantity = IV_MasterLocationCacheDS.GetQuantityOnHand(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.ProductID)
                    if (voTransHis.Lot != null && voTransHis.Lot != string.Empty)
                    {
                        voTransHis.MasLocOHQuantity = (from obj in db.IV_MasLocCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.ProductID && obj.Lot == voTransHis.Lot select obj.OHQuantity).Sum();
                        voTransHis.MasLocCommitQuantity = (from obj in db.IV_MasLocCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.ProductID && obj.Lot == voTransHis.Lot select obj.CommitQuantity).Sum();
                    }
                    else
                    {
                        voTransHis.MasLocOHQuantity = (from obj in db.IV_MasLocCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.ProductID select obj.OHQuantity).Sum();
                        voTransHis.MasLocCommitQuantity = (from obj in db.IV_MasLocCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.ProductID select obj.CommitQuantity).Sum();
                    }

                    // 2. LocationOHQuantity
                    // If MST_TransactionHistoryVO.LocationID > 0
                    // - If MST_TransactionHistoryVO.Lot != null: MST_TransactionHistoryVO.LocationOHQuantity = IV_LocationCacheDS.GetQuantityOnHandByLot(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.ProductID, MST_TransactionHistoryVO.Lot)
                    // - Else MST_TransactionHistoryVO.LocationOHQuantity = IV_LocationCacheDS.GetQuantityOnHand(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.ProductID)
                    if (voTransHis.LocationID > 0)
                    {
                        if (voTransHis.Lot != null && voTransHis.Lot != string.Empty)
                        {
                            voTransHis.MasLocOHQuantity = (from obj in db.IV_LocationCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.ProductID && obj.Lot == voTransHis.Lot && obj.LocationID == voTransHis.LocationID select obj.OHQuantity).Sum();
                            voTransHis.MasLocCommitQuantity = (from obj in db.IV_LocationCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.ProductID && obj.Lot == voTransHis.Lot && obj.LocationID == voTransHis.LocationID select obj.CommitQuantity).Sum();
                        }
                        else
                        {
                            voTransHis.MasLocOHQuantity = (from obj in db.IV_LocationCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.ProductID select obj.OHQuantity).Sum();
                            voTransHis.MasLocCommitQuantity = (from obj in db.IV_LocationCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.ProductID select obj.CommitQuantity).Sum();
                        }
                    }

                    // 3. BinOHQuantity
                    // If MST_TransactionHistoryVO.BinID > 0
                    // - If MST_TransactionHistoryVO.Lot != null: MST_TransactionHistoryVO.BinOHQuantity = IV_BinCacheDS.GetQuantityOnHandByLot(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.BinID, MST_TransactionHistoryVO.ProductID, MST_TransactionHistoryVO.Lot)
                    // - Else MST_TransactionHistoryVO.BinOHQuantity = IV_BinCacheDS.GetQuantityOnHand(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.BinID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.ProductID)

                    if (voTransHis.BinID > 0)
                    {
                        if (voTransHis.Lot != null && voTransHis.Lot != string.Empty)
                        {
                            voTransHis.MasLocOHQuantity = (from obj in db.IV_BinCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.ProductID && obj.Lot == voTransHis.Lot && obj.LocationID == voTransHis.LocationID && voTransHis.BinID == obj.BinID select (obj.OHQuantity - obj.CommitQuantity)).Sum();
                            voTransHis.MasLocCommitQuantity = (from obj in db.IV_BinCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.ProductID && obj.Lot == voTransHis.Lot && obj.LocationID == voTransHis.LocationID && voTransHis.BinID == obj.BinID select obj.CommitQuantity).Sum();
                        }
                        else
                        {
                            voTransHis.MasLocOHQuantity = (from obj in db.IV_BinCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.LocationID select (obj.OHQuantity - obj.CommitQuantity)).Sum();
                            voTransHis.MasLocCommitQuantity = (from obj in db.IV_BinCaches where obj.CCNID == voTransHis.CCNID && obj.MasterLocationID == voTransHis.MasterLocationID && obj.ProductID == voTransHis.LocationID select obj.CommitQuantity).Sum();
                        }
                    }

                    //4. Cost
                    // If ProductID > 0
                    // MST_TransactionHistoryVO.Cost = ITM_CostDS.GetItemCostTotalAmount21ByProductIDCCNID(pintProductID, pintCCNID)
                    if (voTransHis.ProductID > 0)
                    {
                        voTransHis.StdCost = (from obj in db.ITM_Costs where obj.CCNID == voTransHis.CCNID && obj.ProductID == voTransHis.ProductID select obj.ComTotalAmount21).Sum();
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally { trans.Complete(); }
            }
        }
        public void AssignCommonValue(object pobjTransactionHistory)
        {
            MST_TransactionHistoryVO voTransHis = (MST_TransactionHistoryVO)pobjTransactionHistory;
            //1. MasLocOHQuantity
            //- If MST_TransactionHistoryVO.Lot != null: MST_TransactionHistoryVO.MasLocOHQuantity = IV_MasterLocationCacheDS.GetQuantityOnHandByLot(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.ProductID, MST_TransactionHistoryVO.Lot)
            //- Else MST_TransactionHistoryVO.MasLocOHQuantity = IV_MasterLocationCacheDS.GetQuantityOnHand(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.ProductID)
            if (voTransHis.Lot != null && voTransHis.Lot != string.Empty)
            {
                voTransHis.MasLocOHQuantity = (new IV_MasLocCacheDS()).GetQuantityOnHandByLot(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.ProductID, voTransHis.Lot);
                voTransHis.MasLocCommitQuantity = (new IV_MasLocCacheDS()).GetCommitQuantity(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.Lot, voTransHis.ProductID);
            }
            else
            {
                voTransHis.MasLocOHQuantity = (new IV_MasLocCacheDS()).GetQuantityOnHand(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.ProductID);
                voTransHis.MasLocCommitQuantity = (new IV_MasLocCacheDS()).GetCommitQuantity(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.ProductID);
            }

            // 2. LocationOHQuantity
            // If MST_TransactionHistoryVO.LocationID > 0
            // - If MST_TransactionHistoryVO.Lot != null: MST_TransactionHistoryVO.LocationOHQuantity = IV_LocationCacheDS.GetQuantityOnHandByLot(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.ProductID, MST_TransactionHistoryVO.Lot)
            // - Else MST_TransactionHistoryVO.LocationOHQuantity = IV_LocationCacheDS.GetQuantityOnHand(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.ProductID)
            if (voTransHis.LocationID > 0)
            {
                if (voTransHis.Lot != null && voTransHis.Lot != string.Empty)
                {
                    voTransHis.LocationOHQuantity = (new IV_LocationCacheDS()).GetQuantityOnHandByLot(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.LocationID, voTransHis.ProductID, voTransHis.Lot);
                    voTransHis.LocationCommitQuantity = (new IV_LocationCacheDS()).GetCommitQuantity(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.LocationID, voTransHis.Lot, voTransHis.ProductID);
                }
                else
                {
                    voTransHis.LocationOHQuantity = (new IV_LocationCacheDS()).GetQuantityOnHand(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.LocationID, voTransHis.ProductID);
                    voTransHis.LocationCommitQuantity = (new IV_LocationCacheDS()).GetCommitQuantity(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.LocationID, voTransHis.ProductID);
                }
            }

            // 3. BinOHQuantity
            // If MST_TransactionHistoryVO.BinID > 0
            // - If MST_TransactionHistoryVO.Lot != null: MST_TransactionHistoryVO.BinOHQuantity = IV_BinCacheDS.GetQuantityOnHandByLot(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.BinID, MST_TransactionHistoryVO.ProductID, MST_TransactionHistoryVO.Lot)
            // - Else MST_TransactionHistoryVO.BinOHQuantity = IV_BinCacheDS.GetQuantityOnHand(MST_TransactionHistoryVO.CCNID, MST_TransactionHistoryVO.MasterLocationID, MST_TransactionHistoryVO.BinID, MST_TransactionHistoryVO.LocationID, MST_TransactionHistoryVO.ProductID)

            if (voTransHis.BinID > 0)
            {
                if (voTransHis.Lot != null && voTransHis.Lot != string.Empty)
                {
                    voTransHis.BinOHQuantity = (new IV_BinCacheDS()).GetQuantityOnHandByLot(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.LocationID, voTransHis.BinID, voTransHis.ProductID, voTransHis.Lot);
                    voTransHis.BinCommitQuantity = (new IV_BinCacheDS()).GetCommitQuantity(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.LocationID, voTransHis.BinID, voTransHis.Lot, voTransHis.ProductID);
                }
                else
                {
                    voTransHis.BinOHQuantity = (new IV_BinCacheDS()).GetQuantityOnHand(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.LocationID, voTransHis.BinID, voTransHis.ProductID);
                    voTransHis.BinCommitQuantity = (new IV_BinCacheDS()).GetCommitQuantity(voTransHis.CCNID, voTransHis.MasterLocationID, voTransHis.LocationID, voTransHis.BinID, voTransHis.ProductID);
                }
            }

            //4. Cost
            // If ProductID > 0
            // MST_TransactionHistoryVO.Cost = ITM_CostDS.GetItemCostTotalAmount21ByProductIDCCNID(pintProductID, pintCCNID)
            if (voTransHis.ProductID > 0)
            {
                voTransHis.Cost = (new ITM_CostDS()).GetItemCostTotalAmount21ByProductIDCCNID(voTransHis.ProductID, voTransHis.CCNID);
            }
            //Reassign TransactionHistory
            pobjTransactionHistory = voTransHis;
        }

        //[AutoComplete(true)]
        public DataSet ListTransactionHistory(int pintID)
        {
            MST_TransactionHistoryDS dsHist = new MST_TransactionHistoryDS();
            return dsHist.List(pintID);
        }
        //[AutoComplete(true)]
        public DataSet ListTransactionHistory(int pintRefMasterID, int pintTransTypeID)
        {
            MST_TransactionHistoryDS dsHist = new MST_TransactionHistoryDS();
            return dsHist.List(pintRefMasterID, pintTransTypeID);
        }
        #endregion Transaction History Related Methods

        /// <summary>
        ///     Updates all location and master location quantity based on Bin
        /// </summary>
        public void UpdateInventoryData()
        {
            using (var scope = new TransactionScope())
            {
                try
                {
                    using (var dataContext = new PCSDataContext(Utils.Instance.ConnectionString))
                    {
                        var command = new StringBuilder();
                        command.AppendLine("UPDATE IV_LocationCache");
                        command.AppendLine(" SET OHQuantity = (");
                        command.AppendLine(" SELECT SUM(OHQuantity) FROM IV_BinCache");
                        command.AppendLine(" WHERE IV_BinCache.ProductID = IV_LocationCache.ProductID");
                        command.AppendLine(" AND IV_BinCache.LocationID = IV_LocationCache.LocationID)");

                        command.AppendLine(" UPDATE IV_MasLocCache");
                        command.AppendLine(" SET OHQuantity = (");
                        command.AppendLine(" SELECT SUM(OHQuantity) FROM IV_BinCache");
                        command.AppendLine(" WHERE IV_BinCache.ProductID = IV_MasLocCache.ProductID");
                        command.AppendLine(" AND IV_BinCache.MasterLocationID = IV_MasLocCache.MasterLocationID)");

                        dataContext.ExecuteCommand(command.ToString());
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error("Failed to update inventory", ex);
                    throw;
                }
                scope.Complete();
            }
        }
    }
}